package com.klod.news.data.reponsitory


import android.net.http.HttpException
import android.os.Build
import androidx.annotation.RequiresExtension
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import androidx.paging.PagingSource
import androidx.paging.PagingState
import com.klod.news.config.AppConfig.NETWORK_PAGE_SIZE
import com.klod.news.data.api.KtorHomeApi
import com.klod.news.data.bean.NewsDetailBean
import com.klod.news.ext.logE
import kotlinx.coroutines.flow.Flow
import kotlinx.io.IOException
import org.koin.core.annotation.Factory
import org.koin.core.annotation.Single
import org.koin.java.KoinJavaComponent.inject
import kotlin.getValue

@Single
class HomeRepository(private val homeApi: KtorHomeApi) {


    suspend fun getHomeBanner() = homeApi.getHomeBanner()
    suspend fun getNewsBType() = homeApi.getNewsType()
//    suspend fun getHomeNewsList() = homeApi.getHomeNewsList()
    suspend fun getNewsDetail() = homeApi.getNewsDetail()

    fun getHomeList(): Flow<PagingData<NewsDetailBean>> {
        val ps by inject<HomeListDs>(HomeListDs::class.java)
        return Pager(
            config = PagingConfig(
                pageSize = NETWORK_PAGE_SIZE,
                enablePlaceholders = false
            ),
            pagingSourceFactory = { ps}
        ).flow
    }
}

@Factory
class HomeListDs(private val homeApi: KtorHomeApi): PagingSource<Int, NewsDetailBean>() {

    companion object {
        private const val FIST_PAGE = 1
    }

    @RequiresExtension(extension = Build.VERSION_CODES.S, version = 7)
    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, NewsDetailBean> {
        val position = params.key ?: FIST_PAGE

        return try {
            val response = homeApi.getHomeNewsList(position, params.loadSize)
            "${params.loadSize} 加载数量".logE()
            val nextKey = if (response.data.isEmpty()) {
                null
            } else {
                // initial load size = 3 * NETWORK_PAGE_SIZE
                // ensure we're not requesting duplicating items, at the 2nd request
                position + (params.loadSize / NETWORK_PAGE_SIZE)
            }
            LoadResult.Page(
                data = response.data,
                prevKey = if (position == FIST_PAGE) null else position - 1,
                nextKey = nextKey
            )
        } catch (exception: IOException) {
            return LoadResult.Error(exception)
        } catch (exception: HttpException) {
            return LoadResult.Error(exception)
        }
    }
    // The refresh key is used for subsequent refresh calls to PagingSource.load after the initial load
    override fun getRefreshKey(state: PagingState<Int, NewsDetailBean>): Int? {
        // We need to get the previous key (or next key if previous is null) of the page
        // that was closest to the most recently accessed index.
        // Anchor position is the most recently accessed index
//        return state.anchorPosition?.let { anchorPosition ->
//            state.closestPageToPosition(anchorPosition)?.prevKey?.plus(1)
//                ?: state.closestPageToPosition(anchorPosition)?.nextKey?.minus(1)
//        }
        return  FIST_PAGE
    }


}